import os

from celery import Celery
from fastapi import FastAPI
from core.setting import conf
from typing import Optional
from kombu.exceptions import OperationalError
from core.logger import logger as logging
import sys,threading,click,subprocess,signal

app_celery = Celery(
    backend=conf.CELERY_BACKEND_URL,
    broker=conf.CELERY_BROKER_URL,
    broker_connection_retry_on_startup=True,
    include=['celery_tasks.tasks']
)
def get_red_message(msg:str):
    return msg
def starup(app:FastAPI,pool:Optional[str]=None,):
    celery_program=conf.CELERY_ENTRANCE if conf.CELERY_ENTRANCE is not None else "celery"
    pool=pool if pool is not None else "eventlet"
    process = subprocess.Popen([
    celery_program,
    "-A", "celery_tasks.app_celery",
    "worker",
    "--pool", pool
], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
    if not conf.CELERY_INIT:
        return ;
    threading.Thread(target=process.wait).start()
    try:
        inspect = app_celery.control.inspect()
        inspect.ping()
    except OperationalError as e:
        logging.error(
            'EROOR:    {}'.format(str(e)))
        return ;
    app.state.pid = process.pid
    logging.info(f"INFO:     The Celery service has started with PID: {process.pid}.")
    return process.pid
def shutdown(app:FastAPI):
    try:
        pid=app.state.pid
        if pid is None:
            logging.error('EROOR:     The Celery process PID was not found. Please check if the fastapi.state.pid attribute exists.')
            return ;
    except AttributeError:
        logging.error('EROOR:    The Celery process PID was not found. Please check if the fastapi.state.pid attribute exists.')
        return ;
    os.kill(pid,signal.SIGKILL)
    app.state.pid=None
    return True

def reload(app:FastAPI):
    try:
        pid=app.state.pid
        if pid is None:
            starup()
            return True;
    except AttributeError:
        starup(app)
        return True;
    shutdown(app)
    starup(app)
    return True

app_celery.starup=starup
app_celery.shutdown=shutdown
app_celery.reload=reload